// ==========================================================================
// gin-sns 自动生成model扩展代码列表、增、删，改、查、导出，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/model/module/user/user.go
// author：jon
// ==========================================================================
package user

import (
	"errors"

	"xorm.io/builder"

	"gin-sns/app/ginframe/db"
	"gin-sns/app/ginframe/utils/convert"
	"gin-sns/app/ginframe/utils/excel"
	"gin-sns/app/ginframe/utils/page"

	userModel "gin-sns/app/model/module/user"
)

var UserDao = newUserDao()

func newUserDao() *userDao {
	return &userDao{}
}

type userDao struct {
}

//映射数据表
func (d *userDao) TableName() string {
	return "t_user"
}

// 插入数据
func (d *userDao) Insert(e *userModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).Insert(e)
}

// 更新数据
func (d *userDao) Update(e *userModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).ID(e.Id).Update(e)
}

// 删除
func (d *userDao) Delete(e *userModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).ID(e.Id).Delete(e)
}

//批量删除
func (d *userDao) DeleteBatch(ids ...int64) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).In("id", ids).Delete(new(userModel.Entity))
}

// 根据结构体中已有的非空数据来获得单条数据
func (d *userDao) FindOne(e *userModel.Entity) (bool, error) {
	return db.Instance().Engine().Table(d.TableName()).Get(e)
}

// 根据条件查询
func (d *userDao) Find(where, order string) ([]userModel.Entity, error) {
	var list []userModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).Where(where).OrderBy(order).Find(&list)
	return list, err
}

//指定字段集合查询
func (d *userDao) FindIn(column string, args ...interface{}) ([]userModel.Entity, error) {
	var list []userModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).In(column, args).Find(&list)
	return list, err
}

//排除指定字段集合查询
func (d *userDao) FindNotIn(column string, args ...interface{}) ([]userModel.Entity, error) {
	var list []userModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).NotIn(column, args).Find(&list)
	return list, err
}

//根据主键查询数据
func (d *userDao) SelectById(id int64) (*userModel.Entity, error) {
	entity := &userModel.Entity{Id: id}
	have, err := d.FindOne(entity)
	if !have {
		err = errors.New("not found")
		entity = nil
	}
	return entity, err
}

//根据主键删除数据
func (d *userDao) DeleteById(id int64) bool {
	entity := &userModel.Entity{Id: id}
	rs, _ := d.Delete(entity)
	if rs > 0 {
		return true
	}
	return false
}

//批量删除数据记录
func (d *userDao) DeleteByIds(ids string) int64 {
	ida := convert.ToInt64Array(ids, ",")
	result, err := d.DeleteBatch(ida...)
	if err != nil {
		return 0
	}
	return result
}

//根据条件分页查询数据
func (d *userDao) SelectListByPage(param *userModel.SelectPageReq) ([]userModel.Entity, *page.Paging, error) {
	db := db.Instance().Engine()
	p := new(page.Paging)

	if db == nil {
		return nil, p, errors.New("获取数据库连接失败")
	}

	model := db.Table("t_user").Alias("t")

	if param != nil {

		if param.UserName != "" {
			model.Where("t.user_name like ?", "%"+param.UserName+"%")
		}

		if param.UserMobile != "" {
			model.Where("t.user_mobile = ?", param.UserMobile)
		}

		if param.UserEmail != "" {
			model.Where("t.user_email = ?", param.UserEmail)
		}

		if param.Password != "" {
			model.Where("t.password = ?", param.Password)
		}

		if param.Type != 0 {
			model.Where("t.type = ?", param.Type)
		}

		if param.Nickname != "" {
			model.Where("t.nickname like ?", "%"+param.Nickname+"%")
		}

		if param.Sex != 0 {
			model.Where("t.sex = ?", param.Sex)
		}

		if param.Avatar != "" {
			model.Where("t.avatar = ?", param.Avatar)
		}

		if param.Work != "" {
			model.Where("t.work = ?", param.Work)
		}

		if param.Signature != "" {
			model.Where("t.signature = ?", param.Signature)
		}

		if param.Description != "" {
			model.Where("t.description = ?", param.Description)
		}

		if param.Province != 0 {
			model.Where("t.province = ?", param.Province)
		}

		if param.City != 0 {
			model.Where("t.city = ?", param.City)
		}

		if param.Area != 0 {
			model.Where("t.area = ?", param.Area)
		}

		if param.ContactAddr != "" {
			model.Where("t.contact_addr = ?", param.ContactAddr)
		}

		if param.CountFollower != 0 {
			model.Where("t.count_follower = ?", param.CountFollower)
		}

		if param.CountFollowee != 0 {
			model.Where("t.count_followee = ?", param.CountFollowee)
		}

		if param.CountQuestion != 0 {
			model.Where("t.count_question = ?", param.CountQuestion)
		}

		if param.CountAnswer != 0 {
			model.Where("t.count_answer = ?", param.CountAnswer)
		}

		if param.CountPost != 0 {
			model.Where("t.count_post = ?", param.CountPost)
		}

		if param.CountBlog != 0 {
			model.Where("t.count_blog = ?", param.CountBlog)
		}

		if param.Level != 0 {
			model.Where("t.level = ?", param.Level)
		}

		if param.Integral != 0 {
			model.Where("t.integral = ?", param.Integral)
		}

		if param.Status != 0 {
			model.Where("t.status = ?", param.Status)
		}

		if param.BeginTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') >= date_format(?,'%y%m%d') ", param.BeginTime)
		}

		if param.EndTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') <= date_format(?,'%y%m%d') ", param.EndTime)
		}
	}

	totalModel := model.Clone()
	total, err := totalModel.Count()

	if err != nil {
		return nil, p, errors.New("读取行数失败")
	}

	p = page.CreatePaging(param.PageNum, param.PageSize, int(total))

	model.Limit(p.Pagesize, p.StartNum)

	var result []userModel.Entity
	err = model.Find(&result)
	return result, p, err
}

// 导出excel
func (d *userDao) SelectListExport(param *userModel.SelectPageReq, head, col []string) (string, error) {
	db := db.Instance().Engine()

	if db == nil {
		return "", errors.New("获取数据库连接失败")
	}

	build := builder.Select(col...).From(d.TableName(), "t")

	if param != nil {

		if param.UserName != "" {
			build.Where(builder.Like{"t.user_name", param.UserName})
		}

		if param.UserMobile != "" {
			build.Where(builder.Eq{"t.user_mobile": param.UserMobile})
		}

		if param.UserEmail != "" {
			build.Where(builder.Eq{"t.user_email": param.UserEmail})
		}

		if param.Password != "" {
			build.Where(builder.Eq{"t.password": param.Password})
		}

		if param.Type != 0 {
			build.Where(builder.Eq{"t.type": param.Type})
		}

		if param.Nickname != "" {
			build.Where(builder.Like{"t.nickname", param.Nickname})
		}

		if param.Sex != 0 {
			build.Where(builder.Eq{"t.sex": param.Sex})
		}

		if param.Avatar != "" {
			build.Where(builder.Eq{"t.avatar": param.Avatar})
		}

		if param.Work != "" {
			build.Where(builder.Eq{"t.work": param.Work})
		}

		if param.Signature != "" {
			build.Where(builder.Eq{"t.signature": param.Signature})
		}

		if param.Description != "" {
			build.Where(builder.Eq{"t.description": param.Description})
		}

		if param.Province != 0 {
			build.Where(builder.Eq{"t.province": param.Province})
		}

		if param.City != 0 {
			build.Where(builder.Eq{"t.city": param.City})
		}

		if param.Area != 0 {
			build.Where(builder.Eq{"t.area": param.Area})
		}

		if param.ContactAddr != "" {
			build.Where(builder.Eq{"t.contact_addr": param.ContactAddr})
		}

		if param.CountFollower != 0 {
			build.Where(builder.Eq{"t.count_follower": param.CountFollower})
		}

		if param.CountFollowee != 0 {
			build.Where(builder.Eq{"t.count_followee": param.CountFollowee})
		}

		if param.CountQuestion != 0 {
			build.Where(builder.Eq{"t.count_question": param.CountQuestion})
		}

		if param.CountAnswer != 0 {
			build.Where(builder.Eq{"t.count_answer": param.CountAnswer})
		}

		if param.CountPost != 0 {
			build.Where(builder.Eq{"t.count_post": param.CountPost})
		}

		if param.CountBlog != 0 {
			build.Where(builder.Eq{"t.count_blog": param.CountBlog})
		}

		if param.Level != 0 {
			build.Where(builder.Eq{"t.level": param.Level})
		}

		if param.Integral != 0 {
			build.Where(builder.Eq{"t.integral": param.Integral})
		}

		if param.Status != 0 {
			build.Where(builder.Eq{"t.status": param.Status})
		}

		if param.BeginTime != "" {
			build.Where(builder.Gte{"date_format(t.create_time,'%y%m%d')": "date_format('" + param.BeginTime + "','%y%m%d')"})
		}

		if param.EndTime != "" {
			build.Where(builder.Lte{"date_format(t.create_time,'%y%m%d')": "date_format('" + param.EndTime + "','%y%m%d')"})
		}
	}

	sqlStr, _, _ := build.ToSQL()
	arr, err := db.SQL(sqlStr).QuerySliceString()

	path, err := excel.DownlaodExcel(head, arr)

	return path, err
}

//获取所有数据
func (d *userDao) SelectListAll(param *userModel.SelectPageReq) ([]userModel.Entity, error) {
	db := db.Instance().Engine()

	if db == nil {
		return nil, errors.New("获取数据库连接失败")
	}

	model := db.Table(d.TableName()).Alias("t")

	if param != nil {

		if param.UserName != "" {
			model.Where("t.user_name like ?", "%"+param.UserName+"%")
		}

		if param.UserMobile != "" {
			model.Where("t.user_mobile = ?", param.UserMobile)
		}

		if param.UserEmail != "" {
			model.Where("t.user_email = ?", param.UserEmail)
		}

		if param.Password != "" {
			model.Where("t.password = ?", param.Password)
		}

		if param.Type != 0 {
			model.Where("t.type = ?", param.Type)
		}

		if param.Nickname != "" {
			model.Where("t.nickname like ?", "%"+param.Nickname+"%")
		}

		if param.Sex != 0 {
			model.Where("t.sex = ?", param.Sex)
		}

		if param.Avatar != "" {
			model.Where("t.avatar = ?", param.Avatar)
		}

		if param.Work != "" {
			model.Where("t.work = ?", param.Work)
		}

		if param.Signature != "" {
			model.Where("t.signature = ?", param.Signature)
		}

		if param.Description != "" {
			model.Where("t.description = ?", param.Description)
		}

		if param.Province != 0 {
			model.Where("t.province = ?", param.Province)
		}

		if param.City != 0 {
			model.Where("t.city = ?", param.City)
		}

		if param.Area != 0 {
			model.Where("t.area = ?", param.Area)
		}

		if param.ContactAddr != "" {
			model.Where("t.contact_addr = ?", param.ContactAddr)
		}

		if param.CountFollower != 0 {
			model.Where("t.count_follower = ?", param.CountFollower)
		}

		if param.CountFollowee != 0 {
			model.Where("t.count_followee = ?", param.CountFollowee)
		}

		if param.CountQuestion != 0 {
			model.Where("t.count_question = ?", param.CountQuestion)
		}

		if param.CountAnswer != 0 {
			model.Where("t.count_answer = ?", param.CountAnswer)
		}

		if param.CountPost != 0 {
			model.Where("t.count_post = ?", param.CountPost)
		}

		if param.CountBlog != 0 {
			model.Where("t.count_blog = ?", param.CountBlog)
		}

		if param.Level != 0 {
			model.Where("t.level = ?", param.Level)
		}

		if param.Integral != 0 {
			model.Where("t.integral = ?", param.Integral)
		}

		if param.Status != 0 {
			model.Where("t.status = ?", param.Status)
		}

		if param.BeginTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') >= date_format(?,'%y%m%d') ", param.BeginTime)
		}

		if param.EndTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') <= date_format(?,'%y%m%d') ", param.EndTime)
		}
	}

	var result []userModel.Entity
	err := model.Find(&result)
	return result, err
}

//检查邮箱是否已使用
func (d *userDao) CheckEmailUnique(userId int64, email string) bool {
	db := db.Instance().Engine()
	if db == nil {
		return false
	}
	rs, err := db.Table(d.TableName()).Where("user_email=? AND user_id<>?", email, userId).Count()
	if err != nil {
		return false
	}

	if rs > 0 {
		return true
	} else {
		return false
	}
}

//检查邮箱是否存在,存在返回true,否则false
func (d *userDao) CheckEmailUniqueAll(email string) bool {
	db := db.Instance().Engine()
	if db == nil {
		return false
	}
	rs, err := db.Table(d.TableName()).Where("user_email=?", email).Count()
	if err != nil {
		return false
	}

	if rs > 0 {
		return true
	} else {
		return false
	}
}

//检查手机号是否已使用,存在返回true,否则false
func (d *userDao) CheckPhoneUnique(userId int64, phone string) bool {
	db := db.Instance().Engine()
	if db == nil {
		return false
	}
	rs, err := db.Table(d.TableName()).Where("user_mobile = ? AND user_id<>?", phone, userId).Count()
	if err != nil {
		return false
	}

	if rs > 0 {
		return true
	} else {
		return false
	}
}

//检查手机号是否已使用 ,存在返回true,否则false
func (d *userDao) CheckPhoneUniqueAll(phone string) bool {
	db := db.Instance().Engine()
	if db == nil {
		return false
	}
	rs, err := db.Table(d.TableName()).Where("user_mobile = ?", phone).Count()
	if err != nil {
		return false
	}

	if rs > 0 {
		return true
	} else {
		return false
	}
}

//根据登陆名查询用户信息
func (d *userDao) SelectUserByUserName(userName string) (*userModel.Entity, error) {
	var entity userModel.Entity
	entity.UserName = userName
	ok, err := d.FindOne(&entity)
	if ok {
		return &entity, err
	} else {
		return nil, err
	}
}

//根据手机号查询用户信息
func (d *userDao) SelectUserByMobile(mobile string) (*userModel.Entity, error) {
	var entity userModel.Entity
	entity.UserMobile = mobile
	ok, err := d.FindOne(&entity)
	if ok {
		return &entity, err
	} else {
		return nil, err
	}
}

//根据手机号查询用户信息
func (d *userDao) SelectUserByEmail(email string) (*userModel.Entity, error) {
	var entity userModel.Entity
	entity.UserEmail = email
	ok, err := d.FindOne(&entity)
	if ok {
		return &entity, err
	} else {
		return nil, err
	}
}

// 浏览数+1
func (d *userDao) IncrFollowCount(followId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_user set count_follower = count_follower + 1 where id = ?", followId)
}

func (d *userDao) DecrFollowCount(followId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_user set count_follower = count_follower - 1 where id = ?", followId)
}

// 浏览数+1
func (d *userDao) IncrFollowedCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_user set count_followee = count_followee + 1 where id = ?", followedId)
}

func (d *userDao) DecrFollowedCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_user set count_followee = count_followee - 1 where id = ?", followedId)
}
